<?php

use Ratchet\Http\HttpServer;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
use Ratchet\Server\IoServer;
use Ratchet\WebSocket\WsServer;
use React\EventLoop\Factory;
use React\EventLoop\Loop;
use React\Socket\SocketServer;

require __DIR__ . '/vendor/autoload.php';
class stock implements MessageComponentInterface {
    protected $clients;
    protected $lastActivity; // 记录最后活动时间
    protected $pingInterval = 5; // 心跳间隔（秒）
    protected $timeout = 10;    // 超时时间（秒）
    public function __construct() {
        $this->clients = new \SplObjectStorage;
        $this->lastActivity = new \SplObjectStorage;
        $loop = Loop::get();;

        $loop->addPeriodicTimer($this->pingInterval, function () {
            $currentTime = microtime(true);
            foreach ($this->clients as $client) {
                // 发送ping帧并记录时间
                $client->send(json_encode(['type' => 'ping']));
                $this->lastActivity[$client] = $currentTime;
            }

            // 检查超时连接
            foreach ($this->clients as $client) {
                if ($currentTime - $this->lastActivity[$client] > $this->timeout) {
                    $client->close();
                    $this->clients->detach($client);
                    $this->lastActivity->detach($client);
                }
            }
        });
    }

    public function onOpen(ConnectionInterface $conn) {
        $this->clients->attach($conn);
        $this->lastActivity->attach($conn, microtime(true));
    }

    public function onMessage(ConnectionInterface $from, $msg) {

        if ($msg === 'pong') {
            $this->lastActivity[$from] = microtime(true);
            return;
        }

        // 广播消息（排除心跳消息）
        foreach ($this->clients as $client) {
            if ($client !== $from) {
                $client->send($msg);
            }
        }
    }

    public function onClose(ConnectionInterface $conn)
    {
        $this->clients->detach($conn);
    }

    public function onError(ConnectionInterface $conn, \Exception $e)
    {
        $conn->close();
    }
}
$loop = Loop::get();

// 创建 WebSocket 应用服务器
$webSock = new IoServer(
    new HttpServer(new WsServer(new stock())),
    new SocketServer('0.0.0.0:8083', [], $loop), // ✅ 使用 SocketServer 绑定端口
    $loop // ✅ 显式传入事件循环
);

// 启动事件循环
$loop->run();